I. Preliminaries

Loading libraries

library("tidyverse")
library("tibble")
library("msigdbr")
library("ggplot2")
library("TCGAbiolinks")
library("RNAseqQC")
library("DESeq2")
library("ensembldb")
library("purrr")
library("magrittr")
library("vsn")
library("matrixStats")
library("dplyr")
library("grex")
library("survminer")
library("survival")

II. Downloading the TCGA gene expression data

Create a function for downloading TCGA gene expression data.

For more detailed documentation, refer to 2. Differential Gene Expression Analysis - TCGA.Rmd.

GDC_DIR = "../data/public/GDCdata"

query_and_filter_samples <- function(project) {
  query_tumor <- GDCquery(
    project = project,
    data.category = "Transcriptome Profiling",
    data.type = "Gene Expression Quantification",
    experimental.strategy = "RNA-Seq",
    workflow.type = "STAR - Counts",
    access = "open",
    sample.type = "Primary Tumor"
  )
  tumor <- getResults(query_tumor)

  query_normal <- GDCquery(
    project = project,
    data.category = "Transcriptome Profiling",
    data.type = "Gene Expression Quantification",
    experimental.strategy = "RNA-Seq",
    workflow.type = "STAR - Counts",
    access = "open",
    sample.type = "Solid Tissue Normal"
  )
  normal <- getResults(query_normal)

  submitter_ids <- inner_join(tumor, normal, by = "cases.submitter_id") %>%
    dplyr::select(cases.submitter_id)
  tumor <- tumor %>%
    dplyr::filter(cases.submitter_id %in% submitter_ids$cases.submitter_id)
  normal <- normal %>%
    dplyr::filter(cases.submitter_id %in% submitter_ids$cases.submitter_id)

  samples <- rbind(tumor, normal)
  unique(samples$sample_type)

  query_project <- GDCquery(
    project = project,
    data.category = "Transcriptome Profiling",
    data.type = "Gene Expression Quantification",
    experimental.strategy = "RNA-Seq",
    workflow.type = "STAR - Counts",
    access = "open",
    sample.type = c("Solid Tissue Normal", "Primary Tumor"),
    barcode = as.list(samples$sample.submitter_id)
  )

  # If this is your first time running this notebook (i.e., you have not yet downloaded the results of the query in the previous block),
  # uncomment the code block below

  # GDCdownload(
  #   query_coad,
  #   directory = GDC_DIR
  # )

  return(list(samples = samples, query_project = query_project))
}

Download the TCGA gene expression data for colorectal cancer (TCGA-COAD).

projects <- c("TCGA-COAD")

with_results_projects <- c()

samples <- list()
project_data <- list()

for (project in projects) {
  result <- tryCatch(
    {
      result <- query_and_filter_samples(project)
      samples[[project]] <- result$samples
      project_data[[project]] <- result$query_project

      with_results_projects <- c(with_results_projects, project)
    },
    error = function(e) {

    }
  )
}

Running the code block above should generate and populate a directory named GDCdata.

III. Data preprocessing

Construct the RNA-seq count matrix for each cancer type.

tcga_data <- list()
tcga_matrix <- list()

projects <- with_results_projects
for (project in projects) {
  tcga_data[[project]] <- GDCprepare(
    project_data[[project]], 
    directory = GDC_DIR,
    summarizedExperiment = TRUE
  )
}
for (project in projects) {
  count_matrix <- assay(tcga_data[[project]], "unstranded")

  # Remove duplicate entries
  count_matrix_df <- data.frame(count_matrix)
  count_matrix_df <- count_matrix_df[!duplicated(count_matrix_df), ]
  count_matrix <- data.matrix(count_matrix_df)
  rownames(count_matrix) <- cleanid(rownames(count_matrix))
  count_matrix <- count_matrix[!(duplicated(rownames(count_matrix)) | duplicated(rownames(count_matrix), fromLast = TRUE)), ]

  tcga_matrix[[project]] <- count_matrix
}

Format the samples table so that it can be fed as input to DESeq2.

for (project in projects) {
  rownames(samples[[project]]) <- samples[[project]]$cases
  samples[[project]] <- samples[[project]] %>%
    dplyr::select(case = "cases.submitter_id", type = "sample_type")
  samples[[project]]$type <- str_replace(samples[[project]]$type, "Solid Tissue Normal", "normal")
  samples[[project]]$type <- str_replace(samples[[project]]$type, "Primary Tumor", "tumor")
}

DESeq2 requires the row names of samples should be identical to the column names of count_matrix.

for (project in projects) {
  colnames(tcga_matrix[[project]]) <- gsub(x = colnames(tcga_matrix[[project]]), pattern = "\\.", replacement = "-")
  tcga_matrix[[project]] <- tcga_matrix[[project]][, rownames(samples[[project]])]

  # Sanity check
  print(all(colnames(tcga_matrix[[project]]) == rownames(samples[[project]])))
}

IV. Differential gene expression analysis

For more detailed documentation on obtaining the gene set, refer to 7. Differential Gene Expression Analysis - TCGA - Pan-cancer - Unique Genes.Rmd.

RCDdb <- "../data/public/rcd-gene-list/unique-genes/necroptosis-ferroptosis-pyroptosis/"

Write utility functions for filtering the gene sets, performing differential gene expression analysis, plotting the results, and performing variance-stabilizing transformation.

filter_gene_set_and_perform_dgea <- function(genes) {
  tcga_rcd <- list()

  for (project in projects) {
    rownames(genes) <- genes$gene_id
    tcga_rcd[[project]] <- tcga_matrix[[project]][rownames(tcga_matrix[[project]]) %in% genes$gene_id, ]
    tcga_rcd[[project]] <- tcga_rcd[[project]][, rownames(samples[[project]])]
  }

  dds_rcd <- list()
  res_rcd <- list()

  for (project in projects) {
    print(project)
    print("=============")
    dds <- DESeqDataSetFromMatrix(
      countData = tcga_rcd[[project]],
      colData = samples[[project]],
      design = ~type
    )
    dds <- filter_genes(dds, min_count = 10)
    dds$type <- relevel(dds$type, ref = "normal")
    dds_rcd[[project]] <- DESeq(dds)
    res_rcd[[project]] <- results(dds_rcd[[project]])
  }

  deseq.bbl.data <- list()

  for (project in projects) {
    deseq.results <- res_rcd[[project]]
    deseq.bbl.data[[project]] <- data.frame(
      row.names = rownames(deseq.results),
      baseMean = deseq.results$baseMean,
      log2FoldChange = deseq.results$log2FoldChange,
      lfcSE = deseq.results$lfcSE,
      stat = deseq.results$stat,
      pvalue = deseq.results$pvalue,
      padj = deseq.results$padj,
      cancer_type = project,
      gene_symbol = genes[rownames(deseq.results), "gene"]
    )
  }

  deseq.bbl.data.combined <- bind_rows(deseq.bbl.data)
  deseq.bbl.data.combined <- dplyr::filter(deseq.bbl.data.combined, abs(log2FoldChange) >= 1.5 & padj < 0.05)

  return(deseq.bbl.data.combined)
}
plot_dgea <- function(deseq.bbl.data.combined) {
  sizes <- c("<10^-15" = 4, "10^-10" = 3, "10^-5" = 2, "0.05" = 1)

  deseq.bbl.data.combined <- deseq.bbl.data.combined %>%
    mutate(fdr_category = cut(padj,
      breaks = c(-Inf, 1e-15, 1e-10, 1e-5, 0.05),
      labels = c("<10^-15", "10^-10", "10^-5", "0.05"),
      right = FALSE
    ))

  top_genes <- deseq.bbl.data.combined %>%
    group_by(cancer_type) %>%
    mutate(rank = rank(-abs(log2FoldChange))) %>%
    dplyr::filter(rank <= 10) %>%
    ungroup()

  ggplot(top_genes, aes(y = cancer_type, x = gene_symbol, size = fdr_category, fill = log2FoldChange)) +
    geom_point(alpha = 0.5, shape = 21, color = "black") +
    scale_size_manual(values = sizes) +
    scale_fill_gradient2(low = "blue", mid = "white", high = "red", limits = c(min(deseq.bbl.data.combined$log2FoldChange), max(deseq.bbl.data.combined$log2FoldChange))) +
    theme_minimal() +
    theme(
      axis.text.x = element_text(size = 9, angle = 90, hjust = 1)
    ) +
    theme(legend.position = "bottom") +
    theme(legend.position = "bottom") +
    labs(size = "Adjusted p-value", fill = "log2 FC", y = "Cancer type", x = "Gene")
}
perform_vsd <- function(genes) {
  tcga_rcd <- list()

  for (project in projects) {
    rownames(genes) <- genes$gene_id
    tcga_rcd[[project]] <- tcga_matrix[[project]][rownames(tcga_matrix[[project]]) %in% genes$gene_id, ]
    tcga_rcd[[project]] <- tcga_rcd[[project]][, rownames(samples[[project]])]
  }

  vsd_rcd <- list()

  for (project in projects) {
    print(project)
    print("=============")
    dds <- DESeqDataSetFromMatrix(
      countData = tcga_rcd[[project]],
      colData = samples[[project]],
      design = ~type
    )
    dds <- filter_genes(dds, min_count = 10)

    # Perform variance stabilization
    dds <- estimateSizeFactors(dds)
    nsub <- sum(rowMeans(counts(dds, normalized = TRUE)) > 10)
    vsd <- vst(dds, nsub = nsub)
    vsd_rcd[[project]] <- assay(vsd)
  }

  return(vsd_rcd)
}

Pyroptosis

Fetch the gene set of interest.

genes <- read.csv(paste0(RCDdb, "Pyroptosis.csv"))
print(genes)
genes$gene_id <- cleanid(genes$gene_id)
genes <- distinct(genes, gene_id, .keep_all = TRUE)
genes <- subset(genes, gene_id != "")
genes

Filter the genes to include only those in the gene set of interest, and then perform differential gene expression analysis.

deseq.bbl.data.combined <- filter_gene_set_and_perform_dgea(genes)
[1] "TCGA-COAD"
[1] "============="
Warning: some variables in design formula are characters, converting to factorsestimating size factors
estimating dispersions
gene-wise dispersion estimates
mean-dispersion relationship
final dispersion estimates
fitting model and testing
-- replacing outliers and refitting for 3 genes
-- DESeq argument 'minReplicatesForReplace' = 7 
-- original counts are preserved in counts(dds)
estimating dispersions
fitting model and testing
deseq.bbl.data.combined

Plot the results.

plot_dgea(deseq.bbl.data.combined)

Perform variance-stabilizing transformation for further downstream analysis (i.e., for survival analysis).

vsd <- perform_vsd(genes)
[1] "TCGA-COAD"
[1] "============="

V. Downloading the clinical data

Download clinical data from TCGA, and perform some preprocessing: - The deceased column should be FALSE if the patient is alive and TRUE otherwise - The overall_survival column should reflect the follow-up time if the patient is alive and the days to death otherwise

download_clinical_data <- function(project) {
  clinical_data <- GDCquery_clinic(project)
  clinical_data$deceased <- ifelse(clinical_data$vital_status == "Alive", FALSE, TRUE)
  clinical_data$overall_survival <- ifelse(clinical_data$vital_status == "Alive",
    clinical_data$days_to_last_follow_up,
    clinical_data$days_to_death
  )

  return(clinical_data)
}
tcga_clinical <- list()
for (project in projects) {
  tcga_clinical[[project]] <- download_clinical_data(project)
}

VI. Performing survival analysis

Write utility functions for performing survival analysis.

construct_gene_df <- function(gene_of_interest, project) {
  gene_df <- vsd[[project]] %>%
    as.data.frame() %>%
    rownames_to_column(var = "gene_id") %>%
    gather(key = "case_id", value = "counts", -gene_id) %>%
    left_join(., genes, by = "gene_id") %>%
    dplyr::filter(gene == gene_of_interest) %>%
    dplyr::filter(case_id %in% rownames(samples[[project]] %>% dplyr::filter(type == "tumor")))

  q1 <- quantile(gene_df$counts, probs = 0.25)
  q3 <- quantile(gene_df$counts, probs = 0.75)
  gene_df$strata <- ifelse(gene_df$counts >= q3, "HIGH", ifelse(gene_df$counts <= q1, "LOW", "MIDDLE"))
  gene_df <- gene_df %>% dplyr::filter(strata %in% c("LOW", "HIGH"))
  gene_df$case_id <- paste0(sapply(strsplit(as.character(gene_df$case_id), "-"), `[`, 1), '-',
                          sapply(strsplit(as.character(gene_df$case_id), "-"), `[`, 2), '-', 
                          sapply(strsplit(as.character(gene_df$case_id), "-"), `[`, 3))
  gene_df <- merge(gene_df, tcga_clinical[[project]], by.x = "case_id", by.y = "submitter_id")
  
  return(gene_df)
}
compute_surival_fit <- function(gene_df) {
  return (survfit(Surv(overall_survival, deceased) ~ strata, data = gene_df))
}
compute_cox <- function(gene_df) {
  return (coxph(Surv(overall_survival, deceased) ~ strata, data=gene_df))
}
plot_survival <- function(fit) {
  return(ggsurvplot(fit,
    data = gene_df,
    pval = T,
    risk.table = T,
    risk.table.height = 0.3
  ))
}
compute_survival_diff <- function(gene_df) {
  return(survdiff(Surv(overall_survival, deceased) ~ strata, data = gene_df))
}

Perform survival analysis by testing for the difference in the Kaplan-Meier curves using the G-rho family of Harrington and Fleming tests: https://rdrr.io/cran/survival/man/survdiff.html

Our genes of interest are GSDMD (the primary executor of pyroptosis) and the differentially expressed genes.

significant_projects <- c()
significant_genes <- c()

ctr <- 1
for (project in projects) {
  for (gene in c("GSDMD", genes$gene)) {
    cat(project, gene, "\n\n")
    error <- tryCatch (
      {
        gene_df <- construct_gene_df(gene, project)
      },
      error = function(e) {
        cat("\n\n============================\n\n")
        e
      }
    )
    
    if(inherits(error, "error")) next

    if (nrow(gene_df) > 0) {
      fit <- compute_surival_fit(gene_df)
      tryCatch (
        {
          survival <- compute_survival_diff(gene_df)
          cox <- compute_cox(gene_df)
          print(ctr)
          ctr <- ctr + 1
          print(survival)
          cat("\n")
          print(cox)
          print(plot_survival(fit))
          if (pchisq(survival$chisq, length(survival$n)-1, lower.tail = FALSE) < 0.05) {
            significant_projects <- c(significant_projects, project)
            significant_genes <- c(significant_genes, gene)
          }
        },
        error = function(e) {
        }
      )
      
    }
    
    cat("\n\n============================\n\n")
  }
}
TCGA-COAD GSDMD 
Warning: Ran out of iterations and did not converge
[1] 1
Call:
survdiff(formula = Surv(overall_survival, deceased) ~ strata, 
    data = gene_df)

n=3, 21 observations deleted due to missingness.

            N Observed Expected (O-E)^2/E (O-E)^2/V
strata=HIGH 2        2    2.667     0.167         2
strata=LOW  1        1    0.333     1.333         2

 Chisq= 2  on 1 degrees of freedom, p= 0.2 

Call:
coxph(formula = Surv(overall_survival, deceased) ~ strata, data = gene_df)

               coef exp(coef)  se(coef) z p
strataLOW 2.215e+01 4.171e+09 4.566e+04 0 1

Likelihood ratio test=2.2  on 1 df, p=0.1383
n= 3, number of events= 3 
   (21 observations deleted due to missingness)


============================

TCGA-COAD CHMP7 

[1] 2
Call:
survdiff(formula = Surv(overall_survival, deceased) ~ strata, 
    data = gene_df)

n=4, 20 observations deleted due to missingness.

            N Observed Expected (O-E)^2/E (O-E)^2/V
strata=HIGH 3        3     2.92   0.00238    0.0105
strata=LOW  1        1     1.08   0.00641    0.0105

 Chisq= 0  on 1 degrees of freedom, p= 0.9 

Call:
coxph(formula = Surv(overall_survival, deceased) ~ strata, data = gene_df)

             coef exp(coef) se(coef)      z     p
strataLOW -0.1285    0.8794   1.2535 -0.103 0.918

Likelihood ratio test=0.01  on 1 df, p=0.9178
n= 4, number of events= 4 
   (20 observations deleted due to missingness)


============================

TCGA-COAD GSDMC 

[1] 3
Call:
survdiff(formula = Surv(overall_survival, deceased) ~ strata, 
    data = gene_df)

n=8, 16 observations deleted due to missingness.

            N Observed Expected (O-E)^2/E (O-E)^2/V
strata=HIGH 4        4     3.91   0.00198   0.00472
strata=LOW  4        4     4.09   0.00190   0.00472

 Chisq= 0  on 1 degrees of freedom, p= 0.9 

Call:
coxph(formula = Surv(overall_survival, deceased) ~ strata, data = gene_df)

              coef exp(coef) se(coef)      z     p
strataLOW -0.05336   0.94804  0.77685 -0.069 0.945

Likelihood ratio test=0  on 1 df, p=0.9453
n= 8, number of events= 8 
   (16 observations deleted due to missingness)


============================

TCGA-COAD ELANE 

[1] 4
Call:
survdiff(formula = Surv(overall_survival, deceased) ~ strata, 
    data = gene_df)

n=6, 18 observations deleted due to missingness.

            N Observed Expected (O-E)^2/E (O-E)^2/V
strata=HIGH 3        3     1.98     0.521     0.899
strata=LOW  3        3     4.02     0.257     0.899

 Chisq= 0.9  on 1 degrees of freedom, p= 0.3 

Call:
coxph(formula = Surv(overall_survival, deceased) ~ strata, data = gene_df)

             coef exp(coef) se(coef)      z     p
strataLOW -0.8606    0.4229   0.9325 -0.923 0.356

Likelihood ratio test=0.87  on 1 df, p=0.3496
n= 6, number of events= 6 
   (18 observations deleted due to missingness)


============================

TCGA-COAD IRF1 

[1] 5
Call:
survdiff(formula = Surv(overall_survival, deceased) ~ strata, 
    data = gene_df)

n=6, 18 observations deleted due to missingness.

            N Observed Expected (O-E)^2/E (O-E)^2/V
strata=HIGH 3        3     4.52     0.509      2.56
strata=LOW  3        3     1.48     1.551      2.56

 Chisq= 2.6  on 1 degrees of freedom, p= 0.1 

Call:
coxph(formula = Surv(overall_survival, deceased) ~ strata, data = gene_df)

           coef exp(coef) se(coef)    z    p
strataLOW 1.688     5.408    1.172 1.44 0.15

Likelihood ratio test=2.47  on 1 df, p=0.1159
n= 6, number of events= 6 
   (18 observations deleted due to missingness)


============================

TCGA-COAD CYCS 

[1] 6
Call:
survdiff(formula = Surv(overall_survival, deceased) ~ strata, 
    data = gene_df)

n=5, 19 observations deleted due to missingness.

            N Observed Expected (O-E)^2/E (O-E)^2/V
strata=HIGH 2        2     3.07     0.371      1.18
strata=LOW  3        3     1.93     0.589      1.18

 Chisq= 1.2  on 1 degrees of freedom, p= 0.3 

Call:
coxph(formula = Surv(overall_survival, deceased) ~ strata, data = gene_df)

           coef exp(coef) se(coef)    z     p
strataLOW 1.208     3.348    1.173 1.03 0.303

Likelihood ratio test=1.23  on 1 df, p=0.2675
n= 5, number of events= 5 
   (19 observations deleted due to missingness)


============================

TCGA-COAD GSDMA 

[1] 7
Call:
survdiff(formula = Surv(overall_survival, deceased) ~ strata, 
    data = gene_df)

n=6, 18 observations deleted due to missingness.

            N Observed Expected (O-E)^2/E (O-E)^2/V
strata=HIGH 4        4     4.68    0.0997     0.536
strata=LOW  2        2     1.32    0.3546     0.536

 Chisq= 0.5  on 1 degrees of freedom, p= 0.5 

Call:
coxph(formula = Surv(overall_survival, deceased) ~ strata, data = gene_df)

            coef exp(coef) se(coef)     z     p
strataLOW 0.7222    2.0589   1.0075 0.717 0.474

Likelihood ratio test=0.5  on 1 df, p=0.478
n= 6, number of events= 6 
   (18 observations deleted due to missingness)


============================

TCGA-COAD CASP4 

[1] 8
Call:
survdiff(formula = Surv(overall_survival, deceased) ~ strata, 
    data = gene_df)

n=8, 16 observations deleted due to missingness.

            N Observed Expected (O-E)^2/E (O-E)^2/V
strata=HIGH 5        5     5.71     0.089     0.369
strata=LOW  3        3     2.29     0.222     0.369

 Chisq= 0.4  on 1 degrees of freedom, p= 0.5 

Call:
coxph(formula = Surv(overall_survival, deceased) ~ strata, data = gene_df)

            coef exp(coef) se(coef)     z     p
strataLOW 0.4981    1.6456   0.8281 0.601 0.548

Likelihood ratio test=0.36  on 1 df, p=0.5493
n= 8, number of events= 8 
   (16 observations deleted due to missingness)


============================

TCGA-COAD BAK1 

[1] 9
Call:
survdiff(formula = Surv(overall_survival, deceased) ~ strata, 
    data = gene_df)

n=5, 19 observations deleted due to missingness.

            N Observed Expected (O-E)^2/E (O-E)^2/V
strata=HIGH 3        3     2.52    0.0928      0.26
strata=LOW  2        2     2.48    0.0941      0.26

 Chisq= 0.3  on 1 degrees of freedom, p= 0.6 

Call:
coxph(formula = Surv(overall_survival, deceased) ~ strata, data = gene_df)

             coef exp(coef) se(coef)      z     p
strataLOW -0.5892    0.5548   1.1718 -0.503 0.615

Likelihood ratio test=0.27  on 1 df, p=0.6001
n= 5, number of events= 5 
   (19 observations deleted due to missingness)


============================

TCGA-COAD NOD1 

[1] 10
Call:
survdiff(formula = Surv(overall_survival, deceased) ~ strata, 
    data = gene_df)

n=7, 17 observations deleted due to missingness.

            N Observed Expected (O-E)^2/E (O-E)^2/V
strata=HIGH 5        5      4.9   0.00214    0.0079
strata=LOW  2        2      2.1   0.00499    0.0079

 Chisq= 0  on 1 degrees of freedom, p= 0.9 

Call:
coxph(formula = Surv(overall_survival, deceased) ~ strata, data = gene_df)

             coef exp(coef) se(coef)      z     p
strataLOW -0.0781    0.9249   0.8787 -0.089 0.929

Likelihood ratio test=0.01  on 1 df, p=0.9289
n= 7, number of events= 7 
   (17 observations deleted due to missingness)


============================

TCGA-COAD NLRP7 

[1] 11
Call:
survdiff(formula = Surv(overall_survival, deceased) ~ strata, 
    data = gene_df)

n=6, 18 observations deleted due to missingness.

            N Observed Expected (O-E)^2/E (O-E)^2/V
strata=HIGH 2        2    0.783     1.890       2.6
strata=LOW  4        4    5.217     0.284       2.6

 Chisq= 2.6  on 1 degrees of freedom, p= 0.1 

Call:
coxph(formula = Surv(overall_survival, deceased) ~ strata, data = gene_df)

            coef exp(coef) se(coef)     z     p
strataLOW -1.766     0.171    1.235 -1.43 0.153

Likelihood ratio test=2.2  on 1 df, p=0.1382
n= 6, number of events= 6 
   (18 observations deleted due to missingness)


============================

TCGA-COAD CASP3 

[1] 12
Call:
survdiff(formula = Surv(overall_survival, deceased) ~ strata, 
    data = gene_df)

n=4, 20 observations deleted due to missingness.

            N Observed Expected (O-E)^2/E (O-E)^2/V
strata=HIGH 2        2     2.67     0.167     0.615
strata=LOW  2        2     1.33     0.333     0.615

 Chisq= 0.6  on 1 degrees of freedom, p= 0.4 

Call:
coxph(formula = Surv(overall_survival, deceased) ~ strata, data = gene_df)

            coef exp(coef) se(coef)     z     p
strataLOW 0.9406    2.5616   1.2403 0.758 0.448

Likelihood ratio test=0.62  on 1 df, p=0.4325
n= 4, number of events= 4 
   (20 observations deleted due to missingness)


============================

TCGA-COAD GSDMB 

[1] 13
Call:
survdiff(formula = Surv(overall_survival, deceased) ~ strata, 
    data = gene_df)

n=5, 19 observations deleted due to missingness.

            N Observed Expected (O-E)^2/E (O-E)^2/V
strata=HIGH 3        3     3.27    0.0218    0.0739
strata=LOW  2        2     1.73    0.0410    0.0739

 Chisq= 0.1  on 1 degrees of freedom, p= 0.8 

Call:
coxph(formula = Surv(overall_survival, deceased) ~ strata, data = gene_df)

            coef exp(coef) se(coef)     z     p
strataLOW 0.2739    1.3151   1.0107 0.271 0.786

Likelihood ratio test=0.07  on 1 df, p=0.7866
n= 5, number of events= 5 
   (19 observations deleted due to missingness)


============================

TCGA-COAD GZMB 

[1] 14
Call:
survdiff(formula = Surv(overall_survival, deceased) ~ strata, 
    data = gene_df)

n=5, 19 observations deleted due to missingness.

            N Observed Expected (O-E)^2/E (O-E)^2/V
strata=HIGH 3        3    4.017     0.257      1.59
strata=LOW  2        2    0.983     1.051      1.59

 Chisq= 1.6  on 1 degrees of freedom, p= 0.2 

Call:
coxph(formula = Surv(overall_survival, deceased) ~ strata, data = gene_df)

           coef exp(coef) se(coef)     z     p
strataLOW 1.439     4.215    1.236 1.164 0.244

Likelihood ratio test=1.46  on 1 df, p=0.2262
n= 5, number of events= 5 
   (19 observations deleted due to missingness)


============================

TCGA-COAD GSDME 

[1] 15
Call:
survdiff(formula = Surv(overall_survival, deceased) ~ strata, 
    data = gene_df)

n=4, 20 observations deleted due to missingness.

            N Observed Expected (O-E)^2/E (O-E)^2/V
strata=HIGH 1        1     0.25      2.25         3
strata=LOW  3        3     3.75      0.15         3

 Chisq= 3  on 1 degrees of freedom, p= 0.08 

Call:
coxph(formula = Surv(overall_survival, deceased) ~ strata, data = gene_df)

                coef  exp(coef)   se(coef)      z p
strataLOW -2.208e+01  2.562e-10  3.607e+04 -0.001 1

Likelihood ratio test=2.77  on 1 df, p=0.09589
n= 4, number of events= 4 
   (20 observations deleted due to missingness)


============================

TCGA-COAD CHMP3 

[1] 16
Call:
survdiff(formula = Surv(overall_survival, deceased) ~ strata, 
    data = gene_df)

n=4, 20 observations deleted due to missingness.

            N Observed Expected (O-E)^2/E (O-E)^2/V
strata=HIGH 2        2    0.833      1.63      2.88
strata=LOW  2        2    3.167      0.43      2.88

 Chisq= 2.9  on 1 degrees of freedom, p= 0.09 

Call:
coxph(formula = Surv(overall_survival, deceased) ~ strata, data = gene_df)

                coef  exp(coef)   se(coef)      z     p
strataLOW -2.168e+01  3.848e-10  2.943e+04 -0.001 0.999

Likelihood ratio test=3.58  on 1 df, p=0.05836
n= 4, number of events= 4 
   (20 observations deleted due to missingness)


============================

TCGA-COAD DPP9 

[1] 17
Call:
survdiff(formula = Surv(overall_survival, deceased) ~ strata, 
    data = gene_df)

n=3, 21 observations deleted due to missingness.

            N Observed Expected (O-E)^2/E (O-E)^2/V
strata=HIGH 2        2    2.167    0.0128    0.0588
strata=LOW  1        1    0.833    0.0333    0.0588

 Chisq= 0.1  on 1 degrees of freedom, p= 0.8 

Call:
coxph(formula = Surv(overall_survival, deceased) ~ strata, data = gene_df)

            coef exp(coef) se(coef)     z     p
strataLOW 0.3466    1.4142   1.4355 0.241 0.809

Likelihood ratio test=0.06  on 1 df, p=0.8096
n= 3, number of events= 3 
   (21 observations deleted due to missingness)


============================

TCGA-COAD NOD2 

[1] 18
Call:
survdiff(formula = Surv(overall_survival, deceased) ~ strata, 
    data = gene_df)

n=5, 19 observations deleted due to missingness.

            N Observed Expected (O-E)^2/E (O-E)^2/V
strata=HIGH 1        1     1.28    0.0626    0.0979
strata=LOW  4        4     3.72    0.0216    0.0979

 Chisq= 0.1  on 1 degrees of freedom, p= 0.8 

Call:
coxph(formula = Surv(overall_survival, deceased) ~ strata, data = gene_df)

            coef exp(coef) se(coef)     z     p
strataLOW 0.3695    1.4470   1.1865 0.311 0.755

Likelihood ratio test=0.1  on 1 df, p=0.7492
n= 5, number of events= 5 
   (19 observations deleted due to missingness)


============================

TCGA-COAD NLRC4 

[1] 19
Call:
survdiff(formula = Surv(overall_survival, deceased) ~ strata, 
    data = gene_df)

n=5, 19 observations deleted due to missingness.

            N Observed Expected (O-E)^2/E (O-E)^2/V
strata=HIGH 3        3    4.017     0.257      1.59
strata=LOW  2        2    0.983     1.051      1.59

 Chisq= 1.6  on 1 degrees of freedom, p= 0.2 

Call:
coxph(formula = Surv(overall_survival, deceased) ~ strata, data = gene_df)

           coef exp(coef) se(coef)     z     p
strataLOW 1.439     4.215    1.236 1.164 0.244

Likelihood ratio test=1.46  on 1 df, p=0.2262
n= 5, number of events= 5 
   (19 observations deleted due to missingness)


============================

TCGA-COAD GSDMD 

[1] 20
Call:
survdiff(formula = Surv(overall_survival, deceased) ~ strata, 
    data = gene_df)

n=3, 21 observations deleted due to missingness.

            N Observed Expected (O-E)^2/E (O-E)^2/V
strata=HIGH 2        2    2.667     0.167         2
strata=LOW  1        1    0.333     1.333         2

 Chisq= 2  on 1 degrees of freedom, p= 0.2 

Call:
coxph(formula = Surv(overall_survival, deceased) ~ strata, data = gene_df)

               coef exp(coef)  se(coef) z p
strataLOW 2.215e+01 4.171e+09 4.566e+04 0 1

Likelihood ratio test=2.2  on 1 df, p=0.1383
n= 3, number of events= 3 
   (21 observations deleted due to missingness)


============================

TCGA-COAD TIRAP 

[1] 21
Call:
survdiff(formula = Surv(overall_survival, deceased) ~ strata, 
    data = gene_df)

n=7, 17 observations deleted due to missingness.

            N Observed Expected (O-E)^2/E (O-E)^2/V
strata=HIGH 2        2      1.4    0.2547     0.359
strata=LOW  5        5      5.6    0.0638     0.359

 Chisq= 0.4  on 1 degrees of freedom, p= 0.5 

Call:
coxph(formula = Surv(overall_survival, deceased) ~ strata, data = gene_df)

             coef exp(coef) se(coef)      z     p
strataLOW -0.5445    0.5801   0.9202 -0.592 0.554

Likelihood ratio test=0.33  on 1 df, p=0.5629
n= 7, number of events= 7 
   (17 observations deleted due to missingness)


============================

TCGA-COAD SCAF11 

[1] 22
Call:
survdiff(formula = Surv(overall_survival, deceased) ~ strata, 
    data = gene_df)

n=4, 20 observations deleted due to missingness.

            N Observed Expected (O-E)^2/E (O-E)^2/V
strata=HIGH 1        1     2.08     0.563      1.78
strata=LOW  3        3     1.92     0.612      1.78

 Chisq= 1.8  on 1 degrees of freedom, p= 0.2 

Call:
coxph(formula = Surv(overall_survival, deceased) ~ strata, data = gene_df)

               coef exp(coef)  se(coef)     z     p
strataLOW 2.085e+01 1.136e+09 2.490e+04 0.001 0.999

Likelihood ratio test=2.77  on 1 df, p=0.09589
n= 4, number of events= 4 
   (20 observations deleted due to missingness)


============================

TCGA-COAD NLRP6 

[1] 23
Call:
survdiff(formula = Surv(overall_survival, deceased) ~ strata, 
    data = gene_df)

n=7, 17 observations deleted due to missingness.

            N Observed Expected (O-E)^2/E (O-E)^2/V
strata=HIGH 4        4     4.75     0.120     0.417
strata=LOW  3        3     2.25     0.254     0.417

 Chisq= 0.4  on 1 degrees of freedom, p= 0.5 

Call:
coxph(formula = Surv(overall_survival, deceased) ~ strata, data = gene_df)

            coef exp(coef) se(coef)     z     p
strataLOW 0.5293    1.6977   0.8287 0.639 0.523

Likelihood ratio test=0.4  on 1 df, p=0.5252
n= 7, number of events= 7 
   (17 observations deleted due to missingness)


============================

TCGA-COAD AIM2 

[1] 24
Call:
survdiff(formula = Surv(overall_survival, deceased) ~ strata, 
    data = gene_df)

n=6, 18 observations deleted due to missingness.

            N Observed Expected (O-E)^2/E (O-E)^2/V
strata=HIGH 4        4     4.38    0.0335     0.141
strata=LOW  2        2     1.62    0.0909     0.141

 Chisq= 0.1  on 1 degrees of freedom, p= 0.7 

Call:
coxph(formula = Surv(overall_survival, deceased) ~ strata, data = gene_df)

            coef exp(coef) se(coef)     z     p
strataLOW 0.3503    1.4194   0.9368 0.374 0.708

Likelihood ratio test=0.14  on 1 df, p=0.712
n= 6, number of events= 6 
   (18 observations deleted due to missingness)


============================

TCGA-COAD CASP6 

[1] 25
Call:
survdiff(formula = Surv(overall_survival, deceased) ~ strata, 
    data = gene_df)

n=7, 17 observations deleted due to missingness.

            N Observed Expected (O-E)^2/E (O-E)^2/V
strata=HIGH 3        3     3.45    0.0575     0.142
strata=LOW  4        4     3.55    0.0558     0.142

 Chisq= 0.1  on 1 degrees of freedom, p= 0.7 

Call:
coxph(formula = Surv(overall_survival, deceased) ~ strata, data = gene_df)

            coef exp(coef) se(coef)     z     p
strataLOW 0.3150    1.3703   0.8385 0.376 0.707

Likelihood ratio test=0.14  on 1 df, p=0.7076
n= 7, number of events= 7 
   (17 observations deleted due to missingness)


============================

TCGA-COAD NLRP2 

[1] 26
Call:
survdiff(formula = Surv(overall_survival, deceased) ~ strata, 
    data = gene_df)

n=5, 19 observations deleted due to missingness.

            N Observed Expected (O-E)^2/E (O-E)^2/V
strata=HIGH 2        2     1.48    0.1800     0.297
strata=LOW  3        3     3.52    0.0759     0.297

 Chisq= 0.3  on 1 degrees of freedom, p= 0.6 

Call:
coxph(formula = Surv(overall_survival, deceased) ~ strata, data = gene_df)

             coef exp(coef) se(coef)      z    p
strataLOW -0.5493    0.5774   1.0198 -0.539 0.59

Likelihood ratio test=0.29  on 1 df, p=0.5922
n= 5, number of events= 5 
   (19 observations deleted due to missingness)


============================

TCGA-COAD IRF2 

[1] 27
Call:
survdiff(formula = Surv(overall_survival, deceased) ~ strata, 
    data = gene_df)

n=4, 20 observations deleted due to missingness.

            N Observed Expected (O-E)^2/E (O-E)^2/V
strata=HIGH 3        3    3.417    0.0508     0.424
strata=LOW  1        1    0.583    0.2976     0.424

 Chisq= 0.4  on 1 degrees of freedom, p= 0.5 

Call:
coxph(formula = Surv(overall_survival, deceased) ~ strata, data = gene_df)

            coef exp(coef) se(coef)    z     p
strataLOW 0.8959    2.4495   1.4215 0.63 0.529

Likelihood ratio test=0.38  on 1 df, p=0.535
n= 4, number of events= 4 
   (20 observations deleted due to missingness)


============================

TCGA-COAD PJVK 

[1] 28
Call:
survdiff(formula = Surv(overall_survival, deceased) ~ strata, 
    data = gene_df)

n=7, 17 observations deleted due to missingness.

            N Observed Expected (O-E)^2/E (O-E)^2/V
strata=HIGH 3        3        2     0.506     0.856
strata=LOW  4        4        5     0.202     0.856

 Chisq= 0.9  on 1 degrees of freedom, p= 0.4 

Call:
coxph(formula = Surv(overall_survival, deceased) ~ strata, data = gene_df)

             coef exp(coef) se(coef)      z     p
strataLOW -0.8286    0.4366   0.9202 -0.901 0.368

Likelihood ratio test=0.83  on 1 df, p=0.3615
n= 7, number of events= 7 
   (17 observations deleted due to missingness)


============================

TCGA-COAD CASP5 

[1] 29
Call:
survdiff(formula = Surv(overall_survival, deceased) ~ strata, 
    data = gene_df)

n=4, 20 observations deleted due to missingness.

            N Observed Expected (O-E)^2/E (O-E)^2/V
strata=HIGH 3        3     2.92   0.00238    0.0105
strata=LOW  1        1     1.08   0.00641    0.0105

 Chisq= 0  on 1 degrees of freedom, p= 0.9 

Call:
coxph(formula = Surv(overall_survival, deceased) ~ strata, data = gene_df)

             coef exp(coef) se(coef)      z     p
strataLOW -0.1285    0.8794   1.2535 -0.103 0.918

Likelihood ratio test=0.01  on 1 df, p=0.9178
n= 4, number of events= 4 
   (20 observations deleted due to missingness)


============================

TCGA-COAD NLRP1 

[1] 30
Call:
survdiff(formula = Surv(overall_survival, deceased) ~ strata, 
    data = gene_df)

n=8, 16 observations deleted due to missingness.

            N Observed Expected (O-E)^2/E (O-E)^2/V
strata=HIGH 4        4      4.5    0.0546     0.144
strata=LOW  4        4      3.5    0.0700     0.144

 Chisq= 0.1  on 1 degrees of freedom, p= 0.7 

Call:
coxph(formula = Surv(overall_survival, deceased) ~ strata, data = gene_df)

            coef exp(coef) se(coef)     z     p
strataLOW 0.2922    1.3394   0.7736 0.378 0.706

Likelihood ratio test=0.14  on 1 df, p=0.7041
n= 8, number of events= 8 
   (16 observations deleted due to missingness)


============================

TCGA-COAD CASP9 

[1] 31
Call:
survdiff(formula = Surv(overall_survival, deceased) ~ strata, 
    data = gene_df)

n=6, 18 observations deleted due to missingness.

            N Observed Expected (O-E)^2/E (O-E)^2/V
strata=HIGH 3        3     4.27     0.376      1.67
strata=LOW  3        3     1.73     0.926      1.67

 Chisq= 1.7  on 1 degrees of freedom, p= 0.2 

Call:
coxph(formula = Surv(overall_survival, deceased) ~ strata, data = gene_df)

           coef exp(coef) se(coef)     z     p
strataLOW 1.394     4.033    1.164 1.198 0.231

Likelihood ratio test=1.69  on 1 df, p=0.1937
n= 6, number of events= 6 
   (18 observations deleted due to missingness)


============================

TCGA-COAD PLCG1 

[1] 32
Call:
survdiff(formula = Surv(overall_survival, deceased) ~ strata, 
    data = gene_df)

n=5, 19 observations deleted due to missingness.

            N Observed Expected (O-E)^2/E (O-E)^2/V
strata=HIGH 2        2     1.73    0.0410    0.0739
strata=LOW  3        3     3.27    0.0218    0.0739

 Chisq= 0.1  on 1 degrees of freedom, p= 0.8 

Call:
coxph(formula = Surv(overall_survival, deceased) ~ strata, data = gene_df)

             coef exp(coef) se(coef)      z     p
strataLOW -0.2739    0.7604   1.0107 -0.271 0.786

Likelihood ratio test=0.07  on 1 df, p=0.7866
n= 5, number of events= 5 
   (19 observations deleted due to missingness)


============================

TCGA-COAD IL18 

[1] 33
Call:
survdiff(formula = Surv(overall_survival, deceased) ~ strata, 
    data = gene_df)

n=8, 16 observations deleted due to missingness.

            N Observed Expected (O-E)^2/E (O-E)^2/V
strata=HIGH 5        5     4.63    0.0296     0.081
strata=LOW  3        3     3.37    0.0407     0.081

 Chisq= 0.1  on 1 degrees of freedom, p= 0.8 

Call:
coxph(formula = Surv(overall_survival, deceased) ~ strata, data = gene_df)

             coef exp(coef) se(coef)      z     p
strataLOW -0.2207    0.8020   0.7765 -0.284 0.776

Likelihood ratio test=0.08  on 1 df, p=0.7754
n= 8, number of events= 8 
   (16 observations deleted due to missingness)


============================

TCGA-COAD DPP8 

[1] 34
Call:
survdiff(formula = Surv(overall_survival, deceased) ~ strata, 
    data = gene_df)

n=5, 19 observations deleted due to missingness.

            N Observed Expected (O-E)^2/E (O-E)^2/V
strata=HIGH 1        1      0.2     3.200         4
strata=LOW  4        4      4.8     0.133         4

 Chisq= 4  on 1 degrees of freedom, p= 0.05 

Call:
coxph(formula = Surv(overall_survival, deceased) ~ strata, data = gene_df)

                coef  exp(coef)   se(coef)      z     p
strataLOW -2.204e+01  2.674e-10  3.057e+04 -0.001 0.999

Likelihood ratio test=3.22  on 1 df, p=0.07279
n= 5, number of events= 5 
   (19 observations deleted due to missingness)


============================

Display the results only for genes where a significant difference in survival has been reported.

significant_genes
[1] "DPP8"
num_significant_genes <- length(significant_genes)

if (num_significant_genes > 0) {
  for (i in 1 : num_significant_genes) {
    project <- significant_projects[[i]]
    gene <- significant_genes[[i]]
    
    cat(project, gene, "\n\n")
    gene_df <- construct_gene_df(gene, project)
    
    fit <- compute_surival_fit(gene_df)
    survival <- compute_survival_diff(gene_df)
    cox <- compute_cox(gene_df)
    print(survival)
    cat("\n")
    print(cox)
    print(plot_survival(fit))
    
    cat("\n\n============================\n\n")
  } 
}
TCGA-COAD DPP8 
Warning: Loglik converged before variable  1 ; coefficient may be infinite. 
Call:
survdiff(formula = Surv(overall_survival, deceased) ~ strata, 
    data = gene_df)

n=5, 19 observations deleted due to missingness.

            N Observed Expected (O-E)^2/E (O-E)^2/V
strata=HIGH 1        1      0.2     3.200         4
strata=LOW  4        4      4.8     0.133         4

 Chisq= 4  on 1 degrees of freedom, p= 0.05 

Call:
coxph(formula = Surv(overall_survival, deceased) ~ strata, data = gene_df)

                coef  exp(coef)   se(coef)      z     p
strataLOW -2.204e+01  2.674e-10  3.057e+04 -0.001 0.999

Likelihood ratio test=3.22  on 1 df, p=0.07279
n= 5, number of events= 5 
   (19 observations deleted due to missingness)


============================


  1. De La Salle University, Manila, Philippines, ↩︎

  2. De La Salle University, Manila, Philippines, ↩︎

LS0tDQp0aXRsZTogIlN1cnZpdmFsIEFuYWx5c2lzIg0Kc3VidGl0bGU6ICJDb2xvcmVjdGFsIENhbmNlciB8IFB5cm9wdG9zaXMgfCBVbmlxdWUgR2VuZXMgcGVyIFJDRCBUeXBlIHwgR2VuZSBFeHByZXNzaW9uIG9mIFR1bW9yIFNhbXBsZXMiDQphdXRob3I6IA0KICAtIE1hcmsgRWR3YXJkIE0uIEdvbnphbGVzXltEZSBMYSBTYWxsZSBVbml2ZXJzaXR5LCBNYW5pbGEsIFBoaWxpcHBpbmVzLCBnb256YWxlcy5tYXJrZWR3YXJkQGdtYWlsLmNvbV0NCiAgLSBEci4gQW5pc2ggTS5TLiBTaHJlc3RoYV5bRGUgTGEgU2FsbGUgVW5pdmVyc2l0eSwgTWFuaWxhLCBQaGlsaXBwaW5lcywgYW5pc2guc2hyZXN0aGFAZGxzdS5lZHUucGhdDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQojIyBJLiBQcmVsaW1pbmFyaWVzDQoNCiMjIyBMb2FkaW5nIGxpYnJhcmllcw0KDQpgYGB7ciwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0NCmxpYnJhcnkoInRpZHl2ZXJzZSIpDQpsaWJyYXJ5KCJ0aWJibGUiKQ0KbGlicmFyeSgibXNpZ2RiciIpDQpsaWJyYXJ5KCJnZ3Bsb3QyIikNCmxpYnJhcnkoIlRDR0FiaW9saW5rcyIpDQpsaWJyYXJ5KCJSTkFzZXFRQyIpDQpsaWJyYXJ5KCJERVNlcTIiKQ0KbGlicmFyeSgiZW5zZW1ibGRiIikNCmxpYnJhcnkoInB1cnJyIikNCmxpYnJhcnkoIm1hZ3JpdHRyIikNCmxpYnJhcnkoInZzbiIpDQpsaWJyYXJ5KCJtYXRyaXhTdGF0cyIpDQpsaWJyYXJ5KCJkcGx5ciIpDQpsaWJyYXJ5KCJncmV4IikNCmxpYnJhcnkoInN1cnZtaW5lciIpDQpsaWJyYXJ5KCJzdXJ2aXZhbCIpDQpgYGANCg0KIyMgSUkuIERvd25sb2FkaW5nIHRoZSBUQ0dBIGdlbmUgZXhwcmVzc2lvbiBkYXRhIA0KDQpDcmVhdGUgYSBmdW5jdGlvbiBmb3IgZG93bmxvYWRpbmcgVENHQSBnZW5lIGV4cHJlc3Npb24gZGF0YS4gDQoNCkZvciBtb3JlIGRldGFpbGVkIGRvY3VtZW50YXRpb24sIHJlZmVyIHRvIGAyLiBEaWZmZXJlbnRpYWwgR2VuZSBFeHByZXNzaW9uIEFuYWx5c2lzIC0gVENHQS5SbWRgLg0KDQpgYGB7cn0NCkdEQ19ESVIgPSAiLi4vZGF0YS9wdWJsaWMvR0RDZGF0YSINCg0KcXVlcnlfYW5kX2ZpbHRlcl9zYW1wbGVzIDwtIGZ1bmN0aW9uKHByb2plY3QpIHsNCiAgcXVlcnlfdHVtb3IgPC0gR0RDcXVlcnkoDQogICAgcHJvamVjdCA9IHByb2plY3QsDQogICAgZGF0YS5jYXRlZ29yeSA9ICJUcmFuc2NyaXB0b21lIFByb2ZpbGluZyIsDQogICAgZGF0YS50eXBlID0gIkdlbmUgRXhwcmVzc2lvbiBRdWFudGlmaWNhdGlvbiIsDQogICAgZXhwZXJpbWVudGFsLnN0cmF0ZWd5ID0gIlJOQS1TZXEiLA0KICAgIHdvcmtmbG93LnR5cGUgPSAiU1RBUiAtIENvdW50cyIsDQogICAgYWNjZXNzID0gIm9wZW4iLA0KICAgIHNhbXBsZS50eXBlID0gIlByaW1hcnkgVHVtb3IiDQogICkNCiAgdHVtb3IgPC0gZ2V0UmVzdWx0cyhxdWVyeV90dW1vcikNCg0KICBxdWVyeV9ub3JtYWwgPC0gR0RDcXVlcnkoDQogICAgcHJvamVjdCA9IHByb2plY3QsDQogICAgZGF0YS5jYXRlZ29yeSA9ICJUcmFuc2NyaXB0b21lIFByb2ZpbGluZyIsDQogICAgZGF0YS50eXBlID0gIkdlbmUgRXhwcmVzc2lvbiBRdWFudGlmaWNhdGlvbiIsDQogICAgZXhwZXJpbWVudGFsLnN0cmF0ZWd5ID0gIlJOQS1TZXEiLA0KICAgIHdvcmtmbG93LnR5cGUgPSAiU1RBUiAtIENvdW50cyIsDQogICAgYWNjZXNzID0gIm9wZW4iLA0KICAgIHNhbXBsZS50eXBlID0gIlNvbGlkIFRpc3N1ZSBOb3JtYWwiDQogICkNCiAgbm9ybWFsIDwtIGdldFJlc3VsdHMocXVlcnlfbm9ybWFsKQ0KDQogIHN1Ym1pdHRlcl9pZHMgPC0gaW5uZXJfam9pbih0dW1vciwgbm9ybWFsLCBieSA9ICJjYXNlcy5zdWJtaXR0ZXJfaWQiKSAlPiUNCiAgICBkcGx5cjo6c2VsZWN0KGNhc2VzLnN1Ym1pdHRlcl9pZCkNCiAgdHVtb3IgPC0gdHVtb3IgJT4lDQogICAgZHBseXI6OmZpbHRlcihjYXNlcy5zdWJtaXR0ZXJfaWQgJWluJSBzdWJtaXR0ZXJfaWRzJGNhc2VzLnN1Ym1pdHRlcl9pZCkNCiAgbm9ybWFsIDwtIG5vcm1hbCAlPiUNCiAgICBkcGx5cjo6ZmlsdGVyKGNhc2VzLnN1Ym1pdHRlcl9pZCAlaW4lIHN1Ym1pdHRlcl9pZHMkY2FzZXMuc3VibWl0dGVyX2lkKQ0KDQogIHNhbXBsZXMgPC0gcmJpbmQodHVtb3IsIG5vcm1hbCkNCiAgdW5pcXVlKHNhbXBsZXMkc2FtcGxlX3R5cGUpDQoNCiAgcXVlcnlfcHJvamVjdCA8LSBHRENxdWVyeSgNCiAgICBwcm9qZWN0ID0gcHJvamVjdCwNCiAgICBkYXRhLmNhdGVnb3J5ID0gIlRyYW5zY3JpcHRvbWUgUHJvZmlsaW5nIiwNCiAgICBkYXRhLnR5cGUgPSAiR2VuZSBFeHByZXNzaW9uIFF1YW50aWZpY2F0aW9uIiwNCiAgICBleHBlcmltZW50YWwuc3RyYXRlZ3kgPSAiUk5BLVNlcSIsDQogICAgd29ya2Zsb3cudHlwZSA9ICJTVEFSIC0gQ291bnRzIiwNCiAgICBhY2Nlc3MgPSAib3BlbiIsDQogICAgc2FtcGxlLnR5cGUgPSBjKCJTb2xpZCBUaXNzdWUgTm9ybWFsIiwgIlByaW1hcnkgVHVtb3IiKSwNCiAgICBiYXJjb2RlID0gYXMubGlzdChzYW1wbGVzJHNhbXBsZS5zdWJtaXR0ZXJfaWQpDQogICkNCg0KICAjIElmIHRoaXMgaXMgeW91ciBmaXJzdCB0aW1lIHJ1bm5pbmcgdGhpcyBub3RlYm9vayAoaS5lLiwgeW91IGhhdmUgbm90IHlldCBkb3dubG9hZGVkIHRoZSByZXN1bHRzIG9mIHRoZSBxdWVyeSBpbiB0aGUgcHJldmlvdXMgYmxvY2spLA0KICAjIHVuY29tbWVudCB0aGUgY29kZSBibG9jayBiZWxvdw0KDQogICMgR0RDZG93bmxvYWQoDQogICMgICBxdWVyeV9jb2FkLA0KICAjICAgZGlyZWN0b3J5ID0gR0RDX0RJUg0KICAjICkNCg0KICByZXR1cm4obGlzdChzYW1wbGVzID0gc2FtcGxlcywgcXVlcnlfcHJvamVjdCA9IHF1ZXJ5X3Byb2plY3QpKQ0KfQ0KYGBgDQoNCkRvd25sb2FkIHRoZSBUQ0dBIGdlbmUgZXhwcmVzc2lvbiBkYXRhIGZvciBjb2xvcmVjdGFsIGNhbmNlciAoVENHQS1DT0FEKS4NCg0KYGBge3IsIGVjaG8gPSBUUlVFLCBtZXNzYWdlID0gRkFMU0UsIHJlc3VsdHM9ImhpZGUifQ0KcHJvamVjdHMgPC0gYygiVENHQS1DT0FEIikNCg0Kd2l0aF9yZXN1bHRzX3Byb2plY3RzIDwtIGMoKQ0KDQpzYW1wbGVzIDwtIGxpc3QoKQ0KcHJvamVjdF9kYXRhIDwtIGxpc3QoKQ0KDQpmb3IgKHByb2plY3QgaW4gcHJvamVjdHMpIHsNCiAgcmVzdWx0IDwtIHRyeUNhdGNoKA0KICAgIHsNCiAgICAgIHJlc3VsdCA8LSBxdWVyeV9hbmRfZmlsdGVyX3NhbXBsZXMocHJvamVjdCkNCiAgICAgIHNhbXBsZXNbW3Byb2plY3RdXSA8LSByZXN1bHQkc2FtcGxlcw0KICAgICAgcHJvamVjdF9kYXRhW1twcm9qZWN0XV0gPC0gcmVzdWx0JHF1ZXJ5X3Byb2plY3QNCg0KICAgICAgd2l0aF9yZXN1bHRzX3Byb2plY3RzIDwtIGMod2l0aF9yZXN1bHRzX3Byb2plY3RzLCBwcm9qZWN0KQ0KICAgIH0sDQogICAgZXJyb3IgPSBmdW5jdGlvbihlKSB7DQoNCiAgICB9DQogICkNCn0NCmBgYA0KDQpSdW5uaW5nIHRoZSBjb2RlIGJsb2NrIGFib3ZlIHNob3VsZCBnZW5lcmF0ZSBhbmQgcG9wdWxhdGUgYSBkaXJlY3RvcnkgbmFtZWQgYEdEQ2RhdGFgLg0KDQojIyBJSUkuIERhdGEgcHJlcHJvY2Vzc2luZw0KDQpDb25zdHJ1Y3QgdGhlIFJOQS1zZXEgY291bnQgbWF0cml4IGZvciBlYWNoIGNhbmNlciB0eXBlLg0KDQpgYGB7ciwgZWNobyA9IFRSVUUsIG1lc3NhZ2UgPSBGQUxTRSwgcmVzdWx0cz0iaGlkZSJ9DQp0Y2dhX2RhdGEgPC0gbGlzdCgpDQp0Y2dhX21hdHJpeCA8LSBsaXN0KCkNCg0KcHJvamVjdHMgPC0gd2l0aF9yZXN1bHRzX3Byb2plY3RzDQpmb3IgKHByb2plY3QgaW4gcHJvamVjdHMpIHsNCiAgdGNnYV9kYXRhW1twcm9qZWN0XV0gPC0gR0RDcHJlcGFyZSgNCiAgICBwcm9qZWN0X2RhdGFbW3Byb2plY3RdXSwgDQogICAgZGlyZWN0b3J5ID0gR0RDX0RJUiwNCiAgICBzdW1tYXJpemVkRXhwZXJpbWVudCA9IFRSVUUNCiAgKQ0KfQ0KYGBgDQoNCmBgYHtyfQ0KZm9yIChwcm9qZWN0IGluIHByb2plY3RzKSB7DQogIGNvdW50X21hdHJpeCA8LSBhc3NheSh0Y2dhX2RhdGFbW3Byb2plY3RdXSwgInVuc3RyYW5kZWQiKQ0KDQogICMgUmVtb3ZlIGR1cGxpY2F0ZSBlbnRyaWVzDQogIGNvdW50X21hdHJpeF9kZiA8LSBkYXRhLmZyYW1lKGNvdW50X21hdHJpeCkNCiAgY291bnRfbWF0cml4X2RmIDwtIGNvdW50X21hdHJpeF9kZlshZHVwbGljYXRlZChjb3VudF9tYXRyaXhfZGYpLCBdDQogIGNvdW50X21hdHJpeCA8LSBkYXRhLm1hdHJpeChjb3VudF9tYXRyaXhfZGYpDQogIHJvd25hbWVzKGNvdW50X21hdHJpeCkgPC0gY2xlYW5pZChyb3duYW1lcyhjb3VudF9tYXRyaXgpKQ0KICBjb3VudF9tYXRyaXggPC0gY291bnRfbWF0cml4WyEoZHVwbGljYXRlZChyb3duYW1lcyhjb3VudF9tYXRyaXgpKSB8IGR1cGxpY2F0ZWQocm93bmFtZXMoY291bnRfbWF0cml4KSwgZnJvbUxhc3QgPSBUUlVFKSksIF0NCg0KICB0Y2dhX21hdHJpeFtbcHJvamVjdF1dIDwtIGNvdW50X21hdHJpeA0KfQ0KYGBgDQpGb3JtYXQgdGhlIGBzYW1wbGVzYCB0YWJsZSBzbyB0aGF0IGl0IGNhbiBiZSBmZWQgYXMgaW5wdXQgdG8gREVTZXEyLg0KDQpgYGB7cn0NCmZvciAocHJvamVjdCBpbiBwcm9qZWN0cykgew0KICByb3duYW1lcyhzYW1wbGVzW1twcm9qZWN0XV0pIDwtIHNhbXBsZXNbW3Byb2plY3RdXSRjYXNlcw0KICBzYW1wbGVzW1twcm9qZWN0XV0gPC0gc2FtcGxlc1tbcHJvamVjdF1dICU+JQ0KICAgIGRwbHlyOjpzZWxlY3QoY2FzZSA9ICJjYXNlcy5zdWJtaXR0ZXJfaWQiLCB0eXBlID0gInNhbXBsZV90eXBlIikNCiAgc2FtcGxlc1tbcHJvamVjdF1dJHR5cGUgPC0gc3RyX3JlcGxhY2Uoc2FtcGxlc1tbcHJvamVjdF1dJHR5cGUsICJTb2xpZCBUaXNzdWUgTm9ybWFsIiwgIm5vcm1hbCIpDQogIHNhbXBsZXNbW3Byb2plY3RdXSR0eXBlIDwtIHN0cl9yZXBsYWNlKHNhbXBsZXNbW3Byb2plY3RdXSR0eXBlLCAiUHJpbWFyeSBUdW1vciIsICJ0dW1vciIpDQp9DQpgYGANCg0KREVTZXEyIHJlcXVpcmVzIHRoZSByb3cgbmFtZXMgb2YgYHNhbXBsZXNgIHNob3VsZCBiZSBpZGVudGljYWwgdG8gdGhlIGNvbHVtbiBuYW1lcyBvZiBgY291bnRfbWF0cml4YC4NCg0KYGBge3IsIGVjaG8gPSBUUlVFLCByZXN1bHRzPSJoaWRlIn0NCmZvciAocHJvamVjdCBpbiBwcm9qZWN0cykgew0KICBjb2xuYW1lcyh0Y2dhX21hdHJpeFtbcHJvamVjdF1dKSA8LSBnc3ViKHggPSBjb2xuYW1lcyh0Y2dhX21hdHJpeFtbcHJvamVjdF1dKSwgcGF0dGVybiA9ICJcXC4iLCByZXBsYWNlbWVudCA9ICItIikNCiAgdGNnYV9tYXRyaXhbW3Byb2plY3RdXSA8LSB0Y2dhX21hdHJpeFtbcHJvamVjdF1dWywgcm93bmFtZXMoc2FtcGxlc1tbcHJvamVjdF1dKV0NCg0KICAjIFNhbml0eSBjaGVjaw0KICBwcmludChhbGwoY29sbmFtZXModGNnYV9tYXRyaXhbW3Byb2plY3RdXSkgPT0gcm93bmFtZXMoc2FtcGxlc1tbcHJvamVjdF1dKSkpDQp9DQpgYGANCg0KIyMgSVYuIERpZmZlcmVudGlhbCBnZW5lIGV4cHJlc3Npb24gYW5hbHlzaXMNCg0KRm9yIG1vcmUgZGV0YWlsZWQgZG9jdW1lbnRhdGlvbiBvbiBvYnRhaW5pbmcgdGhlIGdlbmUgc2V0LCByZWZlciB0byBgNy4gRGlmZmVyZW50aWFsIEdlbmUgRXhwcmVzc2lvbiBBbmFseXNpcyAtIFRDR0EgLSBQYW4tY2FuY2VyIC0gVW5pcXVlIEdlbmVzLlJtZGAuDQoNCmBgYHtyfQ0KUkNEZGIgPC0gIi4uL2RhdGEvcHVibGljL3JjZC1nZW5lLWxpc3QvdW5pcXVlLWdlbmVzL25lY3JvcHRvc2lzLWZlcnJvcHRvc2lzLXB5cm9wdG9zaXMvIg0KYGBgDQoNCldyaXRlIHV0aWxpdHkgZnVuY3Rpb25zIGZvciBmaWx0ZXJpbmcgdGhlIGdlbmUgc2V0cywgcGVyZm9ybWluZyBkaWZmZXJlbnRpYWwgZ2VuZSBleHByZXNzaW9uIGFuYWx5c2lzLCBwbG90dGluZyB0aGUgcmVzdWx0cywgYW5kIHBlcmZvcm1pbmcgdmFyaWFuY2Utc3RhYmlsaXppbmcgdHJhbnNmb3JtYXRpb24uDQoNCmBgYHtyfQ0KZmlsdGVyX2dlbmVfc2V0X2FuZF9wZXJmb3JtX2RnZWEgPC0gZnVuY3Rpb24oZ2VuZXMpIHsNCiAgdGNnYV9yY2QgPC0gbGlzdCgpDQoNCiAgZm9yIChwcm9qZWN0IGluIHByb2plY3RzKSB7DQogICAgcm93bmFtZXMoZ2VuZXMpIDwtIGdlbmVzJGdlbmVfaWQNCiAgICB0Y2dhX3JjZFtbcHJvamVjdF1dIDwtIHRjZ2FfbWF0cml4W1twcm9qZWN0XV1bcm93bmFtZXModGNnYV9tYXRyaXhbW3Byb2plY3RdXSkgJWluJSBnZW5lcyRnZW5lX2lkLCBdDQogICAgdGNnYV9yY2RbW3Byb2plY3RdXSA8LSB0Y2dhX3JjZFtbcHJvamVjdF1dWywgcm93bmFtZXMoc2FtcGxlc1tbcHJvamVjdF1dKV0NCiAgfQ0KDQogIGRkc19yY2QgPC0gbGlzdCgpDQogIHJlc19yY2QgPC0gbGlzdCgpDQoNCiAgZm9yIChwcm9qZWN0IGluIHByb2plY3RzKSB7DQogICAgcHJpbnQocHJvamVjdCkNCiAgICBwcmludCgiPT09PT09PT09PT09PSIpDQogICAgZGRzIDwtIERFU2VxRGF0YVNldEZyb21NYXRyaXgoDQogICAgICBjb3VudERhdGEgPSB0Y2dhX3JjZFtbcHJvamVjdF1dLA0KICAgICAgY29sRGF0YSA9IHNhbXBsZXNbW3Byb2plY3RdXSwNCiAgICAgIGRlc2lnbiA9IH50eXBlDQogICAgKQ0KICAgIGRkcyA8LSBmaWx0ZXJfZ2VuZXMoZGRzLCBtaW5fY291bnQgPSAxMCkNCiAgICBkZHMkdHlwZSA8LSByZWxldmVsKGRkcyR0eXBlLCByZWYgPSAibm9ybWFsIikNCiAgICBkZHNfcmNkW1twcm9qZWN0XV0gPC0gREVTZXEoZGRzKQ0KICAgIHJlc19yY2RbW3Byb2plY3RdXSA8LSByZXN1bHRzKGRkc19yY2RbW3Byb2plY3RdXSkNCiAgfQ0KDQogIGRlc2VxLmJibC5kYXRhIDwtIGxpc3QoKQ0KDQogIGZvciAocHJvamVjdCBpbiBwcm9qZWN0cykgew0KICAgIGRlc2VxLnJlc3VsdHMgPC0gcmVzX3JjZFtbcHJvamVjdF1dDQogICAgZGVzZXEuYmJsLmRhdGFbW3Byb2plY3RdXSA8LSBkYXRhLmZyYW1lKA0KICAgICAgcm93Lm5hbWVzID0gcm93bmFtZXMoZGVzZXEucmVzdWx0cyksDQogICAgICBiYXNlTWVhbiA9IGRlc2VxLnJlc3VsdHMkYmFzZU1lYW4sDQogICAgICBsb2cyRm9sZENoYW5nZSA9IGRlc2VxLnJlc3VsdHMkbG9nMkZvbGRDaGFuZ2UsDQogICAgICBsZmNTRSA9IGRlc2VxLnJlc3VsdHMkbGZjU0UsDQogICAgICBzdGF0ID0gZGVzZXEucmVzdWx0cyRzdGF0LA0KICAgICAgcHZhbHVlID0gZGVzZXEucmVzdWx0cyRwdmFsdWUsDQogICAgICBwYWRqID0gZGVzZXEucmVzdWx0cyRwYWRqLA0KICAgICAgY2FuY2VyX3R5cGUgPSBwcm9qZWN0LA0KICAgICAgZ2VuZV9zeW1ib2wgPSBnZW5lc1tyb3duYW1lcyhkZXNlcS5yZXN1bHRzKSwgImdlbmUiXQ0KICAgICkNCiAgfQ0KDQogIGRlc2VxLmJibC5kYXRhLmNvbWJpbmVkIDwtIGJpbmRfcm93cyhkZXNlcS5iYmwuZGF0YSkNCiAgZGVzZXEuYmJsLmRhdGEuY29tYmluZWQgPC0gZHBseXI6OmZpbHRlcihkZXNlcS5iYmwuZGF0YS5jb21iaW5lZCwgYWJzKGxvZzJGb2xkQ2hhbmdlKSA+PSAxLjUgJiBwYWRqIDwgMC4wNSkNCg0KICByZXR1cm4oZGVzZXEuYmJsLmRhdGEuY29tYmluZWQpDQp9DQpgYGANCg0KYGBge3J9DQpwbG90X2RnZWEgPC0gZnVuY3Rpb24oZGVzZXEuYmJsLmRhdGEuY29tYmluZWQpIHsNCiAgc2l6ZXMgPC0gYygiPDEwXi0xNSIgPSA0LCAiMTBeLTEwIiA9IDMsICIxMF4tNSIgPSAyLCAiMC4wNSIgPSAxKQ0KDQogIGRlc2VxLmJibC5kYXRhLmNvbWJpbmVkIDwtIGRlc2VxLmJibC5kYXRhLmNvbWJpbmVkICU+JQ0KICAgIG11dGF0ZShmZHJfY2F0ZWdvcnkgPSBjdXQocGFkaiwNCiAgICAgIGJyZWFrcyA9IGMoLUluZiwgMWUtMTUsIDFlLTEwLCAxZS01LCAwLjA1KSwNCiAgICAgIGxhYmVscyA9IGMoIjwxMF4tMTUiLCAiMTBeLTEwIiwgIjEwXi01IiwgIjAuMDUiKSwNCiAgICAgIHJpZ2h0ID0gRkFMU0UNCiAgICApKQ0KDQogIHRvcF9nZW5lcyA8LSBkZXNlcS5iYmwuZGF0YS5jb21iaW5lZCAlPiUNCiAgICBncm91cF9ieShjYW5jZXJfdHlwZSkgJT4lDQogICAgbXV0YXRlKHJhbmsgPSByYW5rKC1hYnMobG9nMkZvbGRDaGFuZ2UpKSkgJT4lDQogICAgZHBseXI6OmZpbHRlcihyYW5rIDw9IDEwKSAlPiUNCiAgICB1bmdyb3VwKCkNCg0KICBnZ3Bsb3QodG9wX2dlbmVzLCBhZXMoeSA9IGNhbmNlcl90eXBlLCB4ID0gZ2VuZV9zeW1ib2wsIHNpemUgPSBmZHJfY2F0ZWdvcnksIGZpbGwgPSBsb2cyRm9sZENoYW5nZSkpICsNCiAgICBnZW9tX3BvaW50KGFscGhhID0gMC41LCBzaGFwZSA9IDIxLCBjb2xvciA9ICJibGFjayIpICsNCiAgICBzY2FsZV9zaXplX21hbnVhbCh2YWx1ZXMgPSBzaXplcykgKw0KICAgIHNjYWxlX2ZpbGxfZ3JhZGllbnQyKGxvdyA9ICJibHVlIiwgbWlkID0gIndoaXRlIiwgaGlnaCA9ICJyZWQiLCBsaW1pdHMgPSBjKG1pbihkZXNlcS5iYmwuZGF0YS5jb21iaW5lZCRsb2cyRm9sZENoYW5nZSksIG1heChkZXNlcS5iYmwuZGF0YS5jb21iaW5lZCRsb2cyRm9sZENoYW5nZSkpKSArDQogICAgdGhlbWVfbWluaW1hbCgpICsNCiAgICB0aGVtZSgNCiAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA5LCBhbmdsZSA9IDkwLCBoanVzdCA9IDEpDQogICAgKSArDQogICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpICsNCiAgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikgKw0KICAgIGxhYnMoc2l6ZSA9ICJBZGp1c3RlZCBwLXZhbHVlIiwgZmlsbCA9ICJsb2cyIEZDIiwgeSA9ICJDYW5jZXIgdHlwZSIsIHggPSAiR2VuZSIpDQp9DQpgYGANCg0KYGBge3J9DQpwZXJmb3JtX3ZzZCA8LSBmdW5jdGlvbihnZW5lcykgew0KICB0Y2dhX3JjZCA8LSBsaXN0KCkNCg0KICBmb3IgKHByb2plY3QgaW4gcHJvamVjdHMpIHsNCiAgICByb3duYW1lcyhnZW5lcykgPC0gZ2VuZXMkZ2VuZV9pZA0KICAgIHRjZ2FfcmNkW1twcm9qZWN0XV0gPC0gdGNnYV9tYXRyaXhbW3Byb2plY3RdXVtyb3duYW1lcyh0Y2dhX21hdHJpeFtbcHJvamVjdF1dKSAlaW4lIGdlbmVzJGdlbmVfaWQsIF0NCiAgICB0Y2dhX3JjZFtbcHJvamVjdF1dIDwtIHRjZ2FfcmNkW1twcm9qZWN0XV1bLCByb3duYW1lcyhzYW1wbGVzW1twcm9qZWN0XV0pXQ0KICB9DQoNCiAgdnNkX3JjZCA8LSBsaXN0KCkNCg0KICBmb3IgKHByb2plY3QgaW4gcHJvamVjdHMpIHsNCiAgICBwcmludChwcm9qZWN0KQ0KICAgIHByaW50KCI9PT09PT09PT09PT09IikNCiAgICBkZHMgPC0gREVTZXFEYXRhU2V0RnJvbU1hdHJpeCgNCiAgICAgIGNvdW50RGF0YSA9IHRjZ2FfcmNkW1twcm9qZWN0XV0sDQogICAgICBjb2xEYXRhID0gc2FtcGxlc1tbcHJvamVjdF1dLA0KICAgICAgZGVzaWduID0gfnR5cGUNCiAgICApDQogICAgZGRzIDwtIGZpbHRlcl9nZW5lcyhkZHMsIG1pbl9jb3VudCA9IDEwKQ0KDQogICAgIyBQZXJmb3JtIHZhcmlhbmNlIHN0YWJpbGl6YXRpb24NCiAgICBkZHMgPC0gZXN0aW1hdGVTaXplRmFjdG9ycyhkZHMpDQogICAgbnN1YiA8LSBzdW0ocm93TWVhbnMoY291bnRzKGRkcywgbm9ybWFsaXplZCA9IFRSVUUpKSA+IDEwKQ0KICAgIHZzZCA8LSB2c3QoZGRzLCBuc3ViID0gbnN1YikNCiAgICB2c2RfcmNkW1twcm9qZWN0XV0gPC0gYXNzYXkodnNkKQ0KICB9DQoNCiAgcmV0dXJuKHZzZF9yY2QpDQp9DQpgYGANCg0KDQojIyMjIFB5cm9wdG9zaXMNCg0KRmV0Y2ggdGhlIGdlbmUgc2V0IG9mIGludGVyZXN0Lg0KDQpgYGB7cn0NCmdlbmVzIDwtIHJlYWQuY3N2KHBhc3RlMChSQ0RkYiwgIlB5cm9wdG9zaXMuY3N2IikpDQpwcmludChnZW5lcykNCmdlbmVzJGdlbmVfaWQgPC0gY2xlYW5pZChnZW5lcyRnZW5lX2lkKQ0KZ2VuZXMgPC0gZGlzdGluY3QoZ2VuZXMsIGdlbmVfaWQsIC5rZWVwX2FsbCA9IFRSVUUpDQpnZW5lcyA8LSBzdWJzZXQoZ2VuZXMsIGdlbmVfaWQgIT0gIiIpDQpnZW5lcw0KYGBgDQoNCkZpbHRlciB0aGUgZ2VuZXMgdG8gaW5jbHVkZSBvbmx5IHRob3NlIGluIHRoZSBnZW5lIHNldCBvZiBpbnRlcmVzdCwgYW5kIHRoZW4gcGVyZm9ybSBkaWZmZXJlbnRpYWwgZ2VuZSBleHByZXNzaW9uIGFuYWx5c2lzLg0KDQpgYGB7cn0NCmRlc2VxLmJibC5kYXRhLmNvbWJpbmVkIDwtIGZpbHRlcl9nZW5lX3NldF9hbmRfcGVyZm9ybV9kZ2VhKGdlbmVzKQ0KZGVzZXEuYmJsLmRhdGEuY29tYmluZWQNCmBgYA0KDQpQbG90IHRoZSByZXN1bHRzLg0KDQpgYGB7cn0NCnBsb3RfZGdlYShkZXNlcS5iYmwuZGF0YS5jb21iaW5lZCkNCmBgYA0KUGVyZm9ybSB2YXJpYW5jZS1zdGFiaWxpemluZyB0cmFuc2Zvcm1hdGlvbiBmb3IgZnVydGhlciBkb3duc3RyZWFtIGFuYWx5c2lzIChpLmUuLCBmb3Igc3Vydml2YWwgYW5hbHlzaXMpLg0KDQpgYGB7ciwgd2FybmluZz1GQUxTRX0NCnZzZCA8LSBwZXJmb3JtX3ZzZChnZW5lcykNCmBgYA0KDQojIyBWLiBEb3dubG9hZGluZyB0aGUgY2xpbmljYWwgZGF0YQ0KDQpEb3dubG9hZCBjbGluaWNhbCBkYXRhIGZyb20gVENHQSwgYW5kIHBlcmZvcm0gc29tZSBwcmVwcm9jZXNzaW5nOg0KLSBUaGUgYGRlY2Vhc2VkYCBjb2x1bW4gc2hvdWxkIGJlIGBGQUxTRWAgaWYgdGhlIHBhdGllbnQgaXMgYWxpdmUgYW5kIGBUUlVFYCBvdGhlcndpc2UNCi0gVGhlIGBvdmVyYWxsX3N1cnZpdmFsYCBjb2x1bW4gc2hvdWxkIHJlZmxlY3QgdGhlIGZvbGxvdy11cCB0aW1lIGlmIHRoZSBwYXRpZW50IGlzIGFsaXZlIGFuZCB0aGUgZGF5cyB0byBkZWF0aCBvdGhlcndpc2UNCg0KYGBge3J9DQpkb3dubG9hZF9jbGluaWNhbF9kYXRhIDwtIGZ1bmN0aW9uKHByb2plY3QpIHsNCiAgY2xpbmljYWxfZGF0YSA8LSBHRENxdWVyeV9jbGluaWMocHJvamVjdCkNCiAgY2xpbmljYWxfZGF0YSRkZWNlYXNlZCA8LSBpZmVsc2UoY2xpbmljYWxfZGF0YSR2aXRhbF9zdGF0dXMgPT0gIkFsaXZlIiwgRkFMU0UsIFRSVUUpDQogIGNsaW5pY2FsX2RhdGEkb3ZlcmFsbF9zdXJ2aXZhbCA8LSBpZmVsc2UoY2xpbmljYWxfZGF0YSR2aXRhbF9zdGF0dXMgPT0gIkFsaXZlIiwNCiAgICBjbGluaWNhbF9kYXRhJGRheXNfdG9fbGFzdF9mb2xsb3dfdXAsDQogICAgY2xpbmljYWxfZGF0YSRkYXlzX3RvX2RlYXRoDQogICkNCg0KICByZXR1cm4oY2xpbmljYWxfZGF0YSkNCn0NCmBgYA0KDQpgYGB7cn0NCnRjZ2FfY2xpbmljYWwgPC0gbGlzdCgpDQpmb3IgKHByb2plY3QgaW4gcHJvamVjdHMpIHsNCiAgdGNnYV9jbGluaWNhbFtbcHJvamVjdF1dIDwtIGRvd25sb2FkX2NsaW5pY2FsX2RhdGEocHJvamVjdCkNCn0NCmBgYA0KDQojIyBWSS4gUGVyZm9ybWluZyBzdXJ2aXZhbCBhbmFseXNpcw0KDQpXcml0ZSB1dGlsaXR5IGZ1bmN0aW9ucyBmb3IgcGVyZm9ybWluZyBzdXJ2aXZhbCBhbmFseXNpcy4NCg0KDQpgYGB7cn0NCmNvbnN0cnVjdF9nZW5lX2RmIDwtIGZ1bmN0aW9uKGdlbmVfb2ZfaW50ZXJlc3QsIHByb2plY3QpIHsNCiAgZ2VuZV9kZiA8LSB2c2RbW3Byb2plY3RdXSAlPiUNCiAgICBhcy5kYXRhLmZyYW1lKCkgJT4lDQogICAgcm93bmFtZXNfdG9fY29sdW1uKHZhciA9ICJnZW5lX2lkIikgJT4lDQogICAgZ2F0aGVyKGtleSA9ICJjYXNlX2lkIiwgdmFsdWUgPSAiY291bnRzIiwgLWdlbmVfaWQpICU+JQ0KICAgIGxlZnRfam9pbiguLCBnZW5lcywgYnkgPSAiZ2VuZV9pZCIpICU+JQ0KICAgIGRwbHlyOjpmaWx0ZXIoZ2VuZSA9PSBnZW5lX29mX2ludGVyZXN0KSAlPiUNCiAgICBkcGx5cjo6ZmlsdGVyKGNhc2VfaWQgJWluJSByb3duYW1lcyhzYW1wbGVzW1twcm9qZWN0XV0gJT4lIGRwbHlyOjpmaWx0ZXIodHlwZSA9PSAidHVtb3IiKSkpDQoNCiAgcTEgPC0gcXVhbnRpbGUoZ2VuZV9kZiRjb3VudHMsIHByb2JzID0gMC4yNSkNCiAgcTMgPC0gcXVhbnRpbGUoZ2VuZV9kZiRjb3VudHMsIHByb2JzID0gMC43NSkNCiAgZ2VuZV9kZiRzdHJhdGEgPC0gaWZlbHNlKGdlbmVfZGYkY291bnRzID49IHEzLCAiSElHSCIsIGlmZWxzZShnZW5lX2RmJGNvdW50cyA8PSBxMSwgIkxPVyIsICJNSURETEUiKSkNCiAgZ2VuZV9kZiA8LSBnZW5lX2RmICU+JSBkcGx5cjo6ZmlsdGVyKHN0cmF0YSAlaW4lIGMoIkxPVyIsICJISUdIIikpDQogIGdlbmVfZGYkY2FzZV9pZCA8LSBwYXN0ZTAoc2FwcGx5KHN0cnNwbGl0KGFzLmNoYXJhY3RlcihnZW5lX2RmJGNhc2VfaWQpLCAiLSIpLCBgW2AsIDEpLCAnLScsDQogICAgICAgICAgICAgICAgICAgICAgICAgIHNhcHBseShzdHJzcGxpdChhcy5jaGFyYWN0ZXIoZ2VuZV9kZiRjYXNlX2lkKSwgIi0iKSwgYFtgLCAyKSwgJy0nLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgc2FwcGx5KHN0cnNwbGl0KGFzLmNoYXJhY3RlcihnZW5lX2RmJGNhc2VfaWQpLCAiLSIpLCBgW2AsIDMpKQ0KICBnZW5lX2RmIDwtIG1lcmdlKGdlbmVfZGYsIHRjZ2FfY2xpbmljYWxbW3Byb2plY3RdXSwgYnkueCA9ICJjYXNlX2lkIiwgYnkueSA9ICJzdWJtaXR0ZXJfaWQiKQ0KICANCiAgcmV0dXJuKGdlbmVfZGYpDQp9DQpgYGANCg0KYGBge3J9DQpjb21wdXRlX3N1cml2YWxfZml0IDwtIGZ1bmN0aW9uKGdlbmVfZGYpIHsNCiAgcmV0dXJuIChzdXJ2Zml0KFN1cnYob3ZlcmFsbF9zdXJ2aXZhbCwgZGVjZWFzZWQpIH4gc3RyYXRhLCBkYXRhID0gZ2VuZV9kZikpDQp9DQpgYGANCg0KYGBge3J9DQpjb21wdXRlX2NveCA8LSBmdW5jdGlvbihnZW5lX2RmKSB7DQogIHJldHVybiAoY294cGgoU3VydihvdmVyYWxsX3N1cnZpdmFsLCBkZWNlYXNlZCkgfiBzdHJhdGEsIGRhdGE9Z2VuZV9kZikpDQp9DQpgYGANCg0KYGBge3J9DQpwbG90X3N1cnZpdmFsIDwtIGZ1bmN0aW9uKGZpdCkgew0KICByZXR1cm4oZ2dzdXJ2cGxvdChmaXQsDQogICAgZGF0YSA9IGdlbmVfZGYsDQogICAgcHZhbCA9IFQsDQogICAgcmlzay50YWJsZSA9IFQsDQogICAgcmlzay50YWJsZS5oZWlnaHQgPSAwLjMNCiAgKSkNCn0NCmBgYA0KDQpgYGB7cn0NCmNvbXB1dGVfc3Vydml2YWxfZGlmZiA8LSBmdW5jdGlvbihnZW5lX2RmKSB7DQogIHJldHVybihzdXJ2ZGlmZihTdXJ2KG92ZXJhbGxfc3Vydml2YWwsIGRlY2Vhc2VkKSB+IHN0cmF0YSwgZGF0YSA9IGdlbmVfZGYpKQ0KfQ0KYGBgDQoNClBlcmZvcm0gc3Vydml2YWwgYW5hbHlzaXMgYnkgdGVzdGluZyBmb3IgdGhlIGRpZmZlcmVuY2UgaW4gdGhlIEthcGxhbi1NZWllciBjdXJ2ZXMgdXNpbmcgdGhlIEctcmhvIGZhbWlseSBvZiBIYXJyaW5ndG9uIGFuZCBGbGVtaW5nIHRlc3RzOiBodHRwczovL3JkcnIuaW8vY3Jhbi9zdXJ2aXZhbC9tYW4vc3VydmRpZmYuaHRtbA0KDQpPdXIgZ2VuZXMgb2YgaW50ZXJlc3QgYXJlIEdTRE1EICh0aGUgcHJpbWFyeSBleGVjdXRvciBvZiBweXJvcHRvc2lzKSBhbmQgdGhlIGRpZmZlcmVudGlhbGx5IGV4cHJlc3NlZCBnZW5lcy4NCg0KYGBge3J9DQpzaWduaWZpY2FudF9wcm9qZWN0cyA8LSBjKCkNCnNpZ25pZmljYW50X2dlbmVzIDwtIGMoKQ0KDQpjdHIgPC0gMQ0KZm9yIChwcm9qZWN0IGluIHByb2plY3RzKSB7DQogIGZvciAoZ2VuZSBpbiBjKCJHU0RNRCIsIGdlbmVzJGdlbmUpKSB7DQogICAgY2F0KHByb2plY3QsIGdlbmUsICJcblxuIikNCiAgICBlcnJvciA8LSB0cnlDYXRjaCAoDQogICAgICB7DQogICAgICAgIGdlbmVfZGYgPC0gY29uc3RydWN0X2dlbmVfZGYoZ2VuZSwgcHJvamVjdCkNCiAgICAgIH0sDQogICAgICBlcnJvciA9IGZ1bmN0aW9uKGUpIHsNCiAgICAgICAgY2F0KCJcblxuPT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4iKQ0KICAgICAgICBlDQogICAgICB9DQogICAgKQ0KICAgIA0KICAgIGlmKGluaGVyaXRzKGVycm9yLCAiZXJyb3IiKSkgbmV4dA0KDQogICAgaWYgKG5yb3coZ2VuZV9kZikgPiAwKSB7DQogICAgICBmaXQgPC0gY29tcHV0ZV9zdXJpdmFsX2ZpdChnZW5lX2RmKQ0KICAgICAgdHJ5Q2F0Y2ggKA0KICAgICAgICB7DQogICAgICAgICAgc3Vydml2YWwgPC0gY29tcHV0ZV9zdXJ2aXZhbF9kaWZmKGdlbmVfZGYpDQogICAgICAgICAgY294IDwtIGNvbXB1dGVfY294KGdlbmVfZGYpDQogICAgICAgICAgcHJpbnQoY3RyKQ0KICAgICAgICAgIGN0ciA8LSBjdHIgKyAxDQogICAgICAgICAgcHJpbnQoc3Vydml2YWwpDQogICAgICAgICAgY2F0KCJcbiIpDQogICAgICAgICAgcHJpbnQoY294KQ0KICAgICAgICAgIHByaW50KHBsb3Rfc3Vydml2YWwoZml0KSkNCiAgICAgICAgICBpZiAocGNoaXNxKHN1cnZpdmFsJGNoaXNxLCBsZW5ndGgoc3Vydml2YWwkbiktMSwgbG93ZXIudGFpbCA9IEZBTFNFKSA8IDAuMDUpIHsNCiAgICAgICAgICAgIHNpZ25pZmljYW50X3Byb2plY3RzIDwtIGMoc2lnbmlmaWNhbnRfcHJvamVjdHMsIHByb2plY3QpDQogICAgICAgICAgICBzaWduaWZpY2FudF9nZW5lcyA8LSBjKHNpZ25pZmljYW50X2dlbmVzLCBnZW5lKQ0KICAgICAgICAgIH0NCiAgICAgICAgfSwNCiAgICAgICAgZXJyb3IgPSBmdW5jdGlvbihlKSB7DQogICAgICAgIH0NCiAgICAgICkNCiAgICAgIA0KICAgIH0NCiAgICANCiAgICBjYXQoIlxuXG49PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiIpDQogIH0NCn0NCmBgYA0KDQpEaXNwbGF5IHRoZSByZXN1bHRzIG9ubHkgZm9yIGdlbmVzIHdoZXJlIGEgc2lnbmlmaWNhbnQgZGlmZmVyZW5jZSBpbiBzdXJ2aXZhbCBoYXMgYmVlbiByZXBvcnRlZC4NCg0KYGBge3J9DQpzaWduaWZpY2FudF9nZW5lcw0KYGBgDQoNCmBgYHtyfQ0KbnVtX3NpZ25pZmljYW50X2dlbmVzIDwtIGxlbmd0aChzaWduaWZpY2FudF9nZW5lcykNCg0KaWYgKG51bV9zaWduaWZpY2FudF9nZW5lcyA+IDApIHsNCiAgZm9yIChpIGluIDEgOiBudW1fc2lnbmlmaWNhbnRfZ2VuZXMpIHsNCiAgICBwcm9qZWN0IDwtIHNpZ25pZmljYW50X3Byb2plY3RzW1tpXV0NCiAgICBnZW5lIDwtIHNpZ25pZmljYW50X2dlbmVzW1tpXV0NCiAgICANCiAgICBjYXQocHJvamVjdCwgZ2VuZSwgIlxuXG4iKQ0KICAgIGdlbmVfZGYgPC0gY29uc3RydWN0X2dlbmVfZGYoZ2VuZSwgcHJvamVjdCkNCiAgICANCiAgICBmaXQgPC0gY29tcHV0ZV9zdXJpdmFsX2ZpdChnZW5lX2RmKQ0KICAgIHN1cnZpdmFsIDwtIGNvbXB1dGVfc3Vydml2YWxfZGlmZihnZW5lX2RmKQ0KICAgIGNveCA8LSBjb21wdXRlX2NveChnZW5lX2RmKQ0KICAgIHByaW50KHN1cnZpdmFsKQ0KICAgIGNhdCgiXG4iKQ0KICAgIHByaW50KGNveCkNCiAgICBwcmludChwbG90X3N1cnZpdmFsKGZpdCkpDQogICAgDQogICAgY2F0KCJcblxuPT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4iKQ0KICB9IA0KfQ0KYGBg